﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.IO;

namespace MimeHelper
{
    public static class Mime
    {
        [DllImport(@"urlmon.dll", CharSet = CharSet.Auto)]
        private extern static System.UInt32 FindMimeFromData(System.UInt32 pBC,
                                                             [MarshalAs(UnmanagedType.LPStr)] System.String pwzUrl,
                                                             [MarshalAs(UnmanagedType.LPArray)] byte[] pBuffer,
                                                             System.UInt32 cbSize,
                                                             [MarshalAs(UnmanagedType.LPStr)] System.String pwzMimeProposed,
                                                             System.UInt32 dwMimeFlags,
                                                             out System.UInt32 ppwzMimeOut,
                                                             System.UInt32 dwReserverd);

        public static String Get(String sExtension)
        {
            string extension = sExtension.ToLower();
            RegistryKey key = Registry.ClassesRoot.OpenSubKey("MIME\\Database\\Content Type");
            foreach (string keyName in key.GetSubKeyNames())
            {
                RegistryKey temp = key.OpenSubKey(keyName);
                if (extension.Equals(temp.GetValue("Extension")))
                {
                    return keyName;
                }
            }

            // Ok well that failed.
            // So time to manually check against a few known possible types.
            switch (sExtension)
            {
                case "rss":
                    return "application/rss+xml";
                case "xml":
                    return "application/xml";
                case "html":
                    return "text/html";
                default:
                    return "unknown/unknown";
            }
        }

        /// <summary>
        /// Get Mime information about stream.
        /// </summary>
        /// <param name="stream">Stream to inspect.</param>
        /// <returns>Mime details.</returns>
        public static String Get(Stream stream)
        {
            Byte[] buffer = new Byte[256];
            try
            {
                int bytesRead;

                if (stream.Length >= 256)
                    bytesRead = stream.Read(buffer, 0, 256);
                else
                    bytesRead = stream.Read(buffer, 0, (int)stream.Length);

                stream.Position = stream.Position - bytesRead;        // Return the pointer.
            }
            catch (Exception)
            {
                return "unknown/unknown";
            }
            try
            {
                System.UInt32 mimetype;
                //FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
                FindMimeFromData(0, null, buffer, 256, null, 0, out mimetype, 0);
                System.IntPtr mimeTypePtr = new IntPtr(mimetype);
                String mime = Marshal.PtrToStringUni(mimeTypePtr);
                Marshal.FreeCoTaskMem(mimeTypePtr);
                return mime;
            }
            catch (Exception)
            {
                return "unknown/unknown";
            }
        } // GetMimeType
    }
}
